<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>ANSI C语言 | whoway</title>
    <meta name="description" content="Personal Blog Website">
    <link rel="icon" href="/images/photo.jpg">
  <link rel="manifest" href="/images/photo.jpg">
  <link rel="apple-touch-icon" href="/images/photo.jpg">
  <meta http-quiv="pragma" cotent="no-cache">
  <meta http-quiv="pragma" cotent="no-cache,must-revalidate">
  <meta http-quiv="expires" cotent="0">
    
    <link rel="preload" href="/assets/css/0.styles.0dbae9ec.css" as="style"><link rel="preload" href="/assets/js/app.c70e21ad.js" as="script"><link rel="preload" href="/assets/js/15.fbdfc4ee.js" as="script"><link rel="prefetch" href="/assets/js/10.15222a53.js"><link rel="prefetch" href="/assets/js/100.7e0e5a86.js"><link rel="prefetch" href="/assets/js/101.efd59f25.js"><link rel="prefetch" href="/assets/js/102.dfbdc06c.js"><link rel="prefetch" href="/assets/js/103.d3ab2109.js"><link rel="prefetch" href="/assets/js/104.117957ef.js"><link rel="prefetch" href="/assets/js/105.046e8ff3.js"><link rel="prefetch" href="/assets/js/106.aebdc17d.js"><link rel="prefetch" href="/assets/js/107.248733c2.js"><link rel="prefetch" href="/assets/js/108.a2fecadc.js"><link rel="prefetch" href="/assets/js/109.35196857.js"><link rel="prefetch" href="/assets/js/11.770642f2.js"><link rel="prefetch" href="/assets/js/110.cf3d973c.js"><link rel="prefetch" href="/assets/js/111.f985889a.js"><link rel="prefetch" href="/assets/js/112.ad614f41.js"><link rel="prefetch" href="/assets/js/113.f666653c.js"><link rel="prefetch" href="/assets/js/114.c6c3f384.js"><link rel="prefetch" href="/assets/js/115.e51d3c2f.js"><link rel="prefetch" href="/assets/js/116.4f4b39f5.js"><link rel="prefetch" href="/assets/js/117.99352e11.js"><link rel="prefetch" href="/assets/js/118.c6ae6572.js"><link rel="prefetch" href="/assets/js/119.4ccbe778.js"><link rel="prefetch" href="/assets/js/12.042a92ff.js"><link rel="prefetch" href="/assets/js/120.edda1c4f.js"><link rel="prefetch" href="/assets/js/121.30a638ed.js"><link rel="prefetch" href="/assets/js/122.6efcefb1.js"><link rel="prefetch" href="/assets/js/123.91e6665b.js"><link rel="prefetch" href="/assets/js/124.f27e3d7e.js"><link rel="prefetch" href="/assets/js/125.c75712d5.js"><link rel="prefetch" href="/assets/js/126.ed756cce.js"><link rel="prefetch" href="/assets/js/127.2f06c74c.js"><link rel="prefetch" href="/assets/js/128.d5f6f30e.js"><link rel="prefetch" href="/assets/js/129.508b7eed.js"><link rel="prefetch" href="/assets/js/13.b5280c37.js"><link rel="prefetch" href="/assets/js/130.dc05f9aa.js"><link rel="prefetch" href="/assets/js/131.e0ba69b1.js"><link rel="prefetch" href="/assets/js/132.d79bcaa4.js"><link rel="prefetch" href="/assets/js/133.34acc01a.js"><link rel="prefetch" href="/assets/js/134.dabf64d5.js"><link rel="prefetch" href="/assets/js/135.ad90c915.js"><link rel="prefetch" href="/assets/js/136.dbb0074f.js"><link rel="prefetch" href="/assets/js/137.284ad365.js"><link rel="prefetch" href="/assets/js/138.a4b6856f.js"><link rel="prefetch" href="/assets/js/139.c9c1e20f.js"><link rel="prefetch" href="/assets/js/14.df02ba38.js"><link rel="prefetch" href="/assets/js/140.8b0a9269.js"><link rel="prefetch" href="/assets/js/141.9c7759c5.js"><link rel="prefetch" href="/assets/js/142.a4201a82.js"><link rel="prefetch" href="/assets/js/143.d7da6e8c.js"><link rel="prefetch" href="/assets/js/144.5e48e65d.js"><link rel="prefetch" href="/assets/js/145.a0e2633c.js"><link rel="prefetch" href="/assets/js/146.3c775f9b.js"><link rel="prefetch" href="/assets/js/147.22add89a.js"><link rel="prefetch" href="/assets/js/148.cfde1009.js"><link rel="prefetch" href="/assets/js/149.ffc835b5.js"><link rel="prefetch" href="/assets/js/150.406c4b20.js"><link rel="prefetch" href="/assets/js/151.b2040eea.js"><link rel="prefetch" href="/assets/js/152.7bc65661.js"><link rel="prefetch" href="/assets/js/153.1d7c65e3.js"><link rel="prefetch" href="/assets/js/154.1309de49.js"><link rel="prefetch" href="/assets/js/155.81d3ee1f.js"><link rel="prefetch" href="/assets/js/156.154a4ef2.js"><link rel="prefetch" href="/assets/js/16.e5eb6147.js"><link rel="prefetch" href="/assets/js/17.57853c4a.js"><link rel="prefetch" href="/assets/js/18.cb9d7518.js"><link rel="prefetch" href="/assets/js/19.f354dc47.js"><link rel="prefetch" href="/assets/js/2.570d8a23.js"><link rel="prefetch" href="/assets/js/20.b5af7fad.js"><link rel="prefetch" href="/assets/js/21.0b1928fe.js"><link rel="prefetch" href="/assets/js/22.f78666de.js"><link rel="prefetch" href="/assets/js/23.29c3f366.js"><link rel="prefetch" href="/assets/js/24.6f596516.js"><link rel="prefetch" href="/assets/js/25.14067b60.js"><link rel="prefetch" href="/assets/js/26.74ba4989.js"><link rel="prefetch" href="/assets/js/27.13d60edd.js"><link rel="prefetch" href="/assets/js/28.9523cb32.js"><link rel="prefetch" href="/assets/js/29.8ec842e9.js"><link rel="prefetch" href="/assets/js/3.3fb3d2e0.js"><link rel="prefetch" href="/assets/js/30.805597a8.js"><link rel="prefetch" href="/assets/js/31.831b195d.js"><link rel="prefetch" href="/assets/js/32.063c672d.js"><link rel="prefetch" href="/assets/js/33.6d93fac3.js"><link rel="prefetch" href="/assets/js/34.56e8263c.js"><link rel="prefetch" href="/assets/js/35.dbe688bb.js"><link rel="prefetch" href="/assets/js/36.dc5af2c1.js"><link rel="prefetch" href="/assets/js/37.0a7494f6.js"><link rel="prefetch" href="/assets/js/38.fe4fc171.js"><link rel="prefetch" href="/assets/js/39.f5ed5e92.js"><link rel="prefetch" href="/assets/js/4.2c405ec8.js"><link rel="prefetch" href="/assets/js/40.fe7e2714.js"><link rel="prefetch" href="/assets/js/41.30b0811d.js"><link rel="prefetch" href="/assets/js/42.76f52d62.js"><link rel="prefetch" href="/assets/js/43.e7bb0817.js"><link rel="prefetch" href="/assets/js/44.ead0e883.js"><link rel="prefetch" href="/assets/js/45.235df046.js"><link rel="prefetch" href="/assets/js/46.5f09e829.js"><link rel="prefetch" href="/assets/js/47.67116354.js"><link rel="prefetch" href="/assets/js/48.31f34543.js"><link rel="prefetch" href="/assets/js/49.10b5ebba.js"><link rel="prefetch" href="/assets/js/5.6f47322c.js"><link rel="prefetch" href="/assets/js/50.c0f0b7f1.js"><link rel="prefetch" href="/assets/js/51.5143f3bf.js"><link rel="prefetch" href="/assets/js/52.eeddfd48.js"><link rel="prefetch" href="/assets/js/53.eb790db5.js"><link rel="prefetch" href="/assets/js/54.8fe5421c.js"><link rel="prefetch" href="/assets/js/55.d8f9004b.js"><link rel="prefetch" href="/assets/js/56.62ac9b92.js"><link rel="prefetch" href="/assets/js/57.a9caec0d.js"><link rel="prefetch" href="/assets/js/58.f93fc522.js"><link rel="prefetch" href="/assets/js/59.a81a03aa.js"><link rel="prefetch" href="/assets/js/6.8c2ea393.js"><link rel="prefetch" href="/assets/js/60.ab782775.js"><link rel="prefetch" href="/assets/js/61.6dd12daf.js"><link rel="prefetch" href="/assets/js/62.76f4b01f.js"><link rel="prefetch" href="/assets/js/63.6f8a4742.js"><link rel="prefetch" href="/assets/js/64.6f8bb1fa.js"><link rel="prefetch" href="/assets/js/65.4120a44b.js"><link rel="prefetch" href="/assets/js/66.360c2d2b.js"><link rel="prefetch" href="/assets/js/67.26f84d32.js"><link rel="prefetch" href="/assets/js/68.68f45e5e.js"><link rel="prefetch" href="/assets/js/69.e311eb56.js"><link rel="prefetch" href="/assets/js/7.6762b2d7.js"><link rel="prefetch" href="/assets/js/70.cea82674.js"><link rel="prefetch" href="/assets/js/71.783ddcf7.js"><link rel="prefetch" href="/assets/js/72.e5467385.js"><link rel="prefetch" href="/assets/js/73.b8fb681b.js"><link rel="prefetch" href="/assets/js/74.1bae37db.js"><link rel="prefetch" href="/assets/js/75.024387e5.js"><link rel="prefetch" href="/assets/js/76.a8e53010.js"><link rel="prefetch" href="/assets/js/77.8c55500a.js"><link rel="prefetch" href="/assets/js/78.7ce90bf5.js"><link rel="prefetch" href="/assets/js/79.ef71713f.js"><link rel="prefetch" href="/assets/js/8.788a6364.js"><link rel="prefetch" href="/assets/js/80.acad589d.js"><link rel="prefetch" href="/assets/js/81.02670d10.js"><link rel="prefetch" href="/assets/js/82.53b7b1ac.js"><link rel="prefetch" href="/assets/js/83.99eb8581.js"><link rel="prefetch" href="/assets/js/84.d1535ce3.js"><link rel="prefetch" href="/assets/js/85.fe2b7de9.js"><link rel="prefetch" href="/assets/js/86.41850272.js"><link rel="prefetch" href="/assets/js/87.1cdc6df9.js"><link rel="prefetch" href="/assets/js/88.01bf3461.js"><link rel="prefetch" href="/assets/js/89.17c69819.js"><link rel="prefetch" href="/assets/js/9.3813842d.js"><link rel="prefetch" href="/assets/js/90.f6ae7e35.js"><link rel="prefetch" href="/assets/js/91.507bc284.js"><link rel="prefetch" href="/assets/js/92.90551782.js"><link rel="prefetch" href="/assets/js/93.dc442d78.js"><link rel="prefetch" href="/assets/js/94.315f4e94.js"><link rel="prefetch" href="/assets/js/95.ccd6c6bf.js"><link rel="prefetch" href="/assets/js/96.0c6d89d0.js"><link rel="prefetch" href="/assets/js/97.1a9f10a9.js"><link rel="prefetch" href="/assets/js/98.43be3caa.js"><link rel="prefetch" href="/assets/js/99.54c8207b.js">
    <link rel="stylesheet" href="/assets/css/0.styles.0dbae9ec.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><!----> <span class="site-name">whoway</span></a> <div class="links" style="max-width:nullpx;"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">🎓Coding</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/00.Coding/TheBeautyOfProgramming/" class="nav-link">🔖编程之美题解</a></li><li class="dropdown-item"><!----> <a href="/00.Coding/CodeWarehouse/" class="nav-link">🔖代码意识流</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">🚀语言</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/01.Language/Overview/" class="nav-link">🔖概述</a></li><li class="dropdown-item"><!----> <a href="/01.Language/C/" class="nav-link router-link-active">⭐️C</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Cpp/" class="nav-link">🚀C++</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Java/" class="nav-link">☕️Java</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Python/" class="nav-link">🧩Python3</a></li></ul></div></div><div class="nav-item"><a href="/02.Hardware/" class="nav-link">✔️硬件基础</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">⭐️软件基础</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/03.Software/01.DataStructureAndAlgorithm/" class="nav-link">🐾数据结构和算法</a></li><li class="dropdown-item"><!----> <a href="/03.Software/02.OS/" class="nav-link">💻操作系统</a></li><li class="dropdown-item"><!----> <a href="/03.Software/03.Net/" class="nav-link">☁️计算机网络</a></li><li class="dropdown-item"><!----> <a href="/03.Software/04.SE/" class="nav-link">✅软件工程</a></li></ul></div></div><div class="nav-item"><a href="/04.Database/" class="nav-link">🎨数据库</a></div><div class="nav-item"><a href="/05.Engineer/" class="nav-link">🔖学术/工程</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">⚙️工具</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/06.Tools/01.employment/" class="nav-link">🔖求职</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/02.efficiency/" class="nav-link">🚀效能</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/03.windows/" class="nav-link">⚙️Windows</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/04.design/" class="nav-link">🧩设计</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/05.linux/" class="nav-link">🐉Linux</a></li></ul></div></div><div class="nav-item"><a href="https://github.com/whoway" target="_blank" rel="noopener noreferrer" class="nav-link external">
  GitHub
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div> <!----></nav></div></header> <div class="sidebar-mask"></div> <div class="sidebar"><nav class="nav-links"><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">🎓Coding</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/00.Coding/TheBeautyOfProgramming/" class="nav-link">🔖编程之美题解</a></li><li class="dropdown-item"><!----> <a href="/00.Coding/CodeWarehouse/" class="nav-link">🔖代码意识流</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">🚀语言</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/01.Language/Overview/" class="nav-link">🔖概述</a></li><li class="dropdown-item"><!----> <a href="/01.Language/C/" class="nav-link router-link-active">⭐️C</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Cpp/" class="nav-link">🚀C++</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Java/" class="nav-link">☕️Java</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Python/" class="nav-link">🧩Python3</a></li></ul></div></div><div class="nav-item"><a href="/02.Hardware/" class="nav-link">✔️硬件基础</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">⭐️软件基础</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/03.Software/01.DataStructureAndAlgorithm/" class="nav-link">🐾数据结构和算法</a></li><li class="dropdown-item"><!----> <a href="/03.Software/02.OS/" class="nav-link">💻操作系统</a></li><li class="dropdown-item"><!----> <a href="/03.Software/03.Net/" class="nav-link">☁️计算机网络</a></li><li class="dropdown-item"><!----> <a href="/03.Software/04.SE/" class="nav-link">✅软件工程</a></li></ul></div></div><div class="nav-item"><a href="/04.Database/" class="nav-link">🎨数据库</a></div><div class="nav-item"><a href="/05.Engineer/" class="nav-link">🔖学术/工程</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">⚙️工具</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/06.Tools/01.employment/" class="nav-link">🔖求职</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/02.efficiency/" class="nav-link">🚀效能</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/03.windows/" class="nav-link">⚙️Windows</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/04.design/" class="nav-link">🧩设计</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/05.linux/" class="nav-link">🐉Linux</a></li></ul></div></div><div class="nav-item"><a href="https://github.com/whoway" target="_blank" rel="noopener noreferrer" class="nav-link external">
  GitHub
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div> <!----></nav>  <ul class="sidebar-links"><li><div class="sidebar-group first"><p class="sidebar-heading open"><span>ANSI C语言</span> <!----></p> <ul class="sidebar-group-items"><li><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#目录" class="sidebar-link">目录</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#c语言学习的”临界点“" class="sidebar-link">C语言学习的”临界点“</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#💬辨析：声明和定义" class="sidebar-link">💬辨析：声明和定义</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#💬辨析：初始化和赋值" class="sidebar-link">💬辨析：初始化和赋值</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#⏰c语言标准历史" class="sidebar-link">⏰C语言标准历史</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#_1-标准k-r-c" class="sidebar-link">1.标准K&amp;R C</a></li><li class="sidebar-sub-header"><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#_2-标准ansi-c、iso-c、c89、c90-（重点）" class="sidebar-link">2.标准ANSI C、ISO C、C89、C90  （重点）</a></li><li class="sidebar-sub-header"><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#_3-c99标准（2000）" class="sidebar-link">3.C99标准（2000）</a></li><li class="sidebar-sub-header"><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#_4-c11标准（2011）" class="sidebar-link">4.C11标准（2011）</a></li></ul></li><li><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#✅语法篇" class="sidebar-link">✅语法篇</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#c和c-变量命名规则探讨？" class="sidebar-link">C和C++变量命名规则探讨？🤔</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#_01-switch语法⭐️" class="sidebar-link">01.switch语法⭐️</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#⭐️类型转换" class="sidebar-link">⭐️类型转换?</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#✔️参加位运算的数据其类型不能是？" class="sidebar-link">✔️参加位运算的数据其类型不能是？</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#_02-常用ascii码值记忆法" class="sidebar-link">02.常用ASCII码值记忆法</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#_03-数组的『初始化方式』⭐️" class="sidebar-link">03.数组的『初始化方式』⭐️</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#_3-1-问题由来" class="sidebar-link">3.1.问题由来</a></li><li class="sidebar-sub-header"><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#_3-2-完全初始化" class="sidebar-link">3.2.完全初始化</a></li><li class="sidebar-sub-header"><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#_2-3-完全不初始化（uninitialized）" class="sidebar-link">2.3.完全不初始化（uninitialized）</a></li><li class="sidebar-sub-header"><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#_2-4-不完全初始化" class="sidebar-link">2.4.不完全初始化</a></li><li class="sidebar-sub-header"><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#_2-5-假装初始化（我编的-）" class="sidebar-link">2.5.假装初始化（我编的..）</a></li></ul></li><li><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#_04-union『c语言中』" class="sidebar-link">04.union『C语言中』</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#_1-union" class="sidebar-link">1.union</a></li><li class="sidebar-sub-header"><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#_2-union的特点" class="sidebar-link">2.union的特点</a></li></ul></li><li><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#_05-位段（也叫位域）bit-field" class="sidebar-link">05.位段（也叫位域）Bit field</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#_1、引言" class="sidebar-link">1、引言</a></li><li class="sidebar-sub-header"><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#_2、语法" class="sidebar-link">2、语法</a></li><li class="sidebar-sub-header"><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#_3、位段的特点和『内存对齐』" class="sidebar-link">3、位段的特点和『内存对齐』</a></li></ul></li><li><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#_06-c语言常量和c-常量" class="sidebar-link">06.C语言常量和C++常量</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#_6-1-整数常量" class="sidebar-link">6.1.整数常量</a></li><li class="sidebar-sub-header"><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#_6-2-浮点常量" class="sidebar-link">6.2.浮点常量</a></li><li class="sidebar-sub-header"><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#_6-3-字符常量-a" class="sidebar-link">6.3.字符常量'a'</a></li><li class="sidebar-sub-header"><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#_6-4-字符串常量-a" class="sidebar-link">6.4.字符串常量&quot;a&quot;</a></li><li class="sidebar-sub-header"><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#_6-5-布尔型常量" class="sidebar-link">6.5.布尔型常量</a></li></ul></li><li><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#_07-c语言static成员" class="sidebar-link">07.C语言static成员</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#🍀详解c语言中const" class="sidebar-link">🍀详解C语言中const</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#_1-概述：" class="sidebar-link">1.概述：</a></li><li class="sidebar-sub-header"><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#_2-基本用法：" class="sidebar-link">2.基本用法：</a></li></ul></li><li><a href="/01.Language/C/01.ANSIC%E8%AF%AD%E8%A8%80.html#参考资料" class="sidebar-link">参考资料</a><ul class="sidebar-sub-headers"></ul></li></ul></div></li></ul> </div> <div class="page"> <div class="content"><h1 id="ansi-c语言"><a href="#ansi-c语言" class="header-anchor">#</a> ANSI C语言</h1> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>&lt;font style=&quot;background:yellow&quot;&gt;
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><h2 id="目录"><a href="#目录" class="header-anchor">#</a> 目录</h2> <p>[TOC]</p> <h2 id="c语言学习的”临界点“"><a href="#c语言学习的”临界点“" class="header-anchor">#</a> C语言学习的”临界点“</h2> <p>突破学校传统教学C语言桎梏的几个重要知识</p> <ul><li>1、内存管理『记住内存管理的stack、heap、.bss、.data』</li> <li>2、指针『1级指针、2级指针作为函数的输入和输出、多级指针定理、函数指针、数组指针、常量指针、源码阅读+工程级项目接口设计』</li> <li>3、结构体的设计『<strong>数据结构的基础</strong>、C++封装思想的基础』</li> <li>4、数组和指针辨析</li> <li>5、C语言写错误日志『文件输入输出、传统教学不强化的点』</li> <li>6、Windows和Linux下的动态链接库设计『大型工程项目基础、Linux下依赖性的来源』</li></ul> <h2 id="💬辨析：声明和定义"><a href="#💬辨析：声明和定义" class="header-anchor">#</a> 💬辨析：声明和定义</h2> <blockquote><p><strong>声明≠定义</strong></p></blockquote> <ul><li><strong>声明</strong>（Declaration）：是指向编译器说明一个变量或函数的信息，包括：名字、类型、初始值等，即声明变量、函数的属性细节；</li> <li><strong>定义</strong>（Definition）：则指明变量、函数存储在哪里，当定义发生时，系统为变量或函数分配内存单元。</li></ul> <blockquote><p>参考：<a href="https://linhongbo.com/posts/difference-between-definition-and-declaration/" target="_blank" rel="noopener noreferrer">声明（Declaration）与定义（Definition）的区别<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p></blockquote> <h2 id="💬辨析：初始化和赋值"><a href="#💬辨析：初始化和赋值" class="header-anchor">#</a> 💬辨析：初始化和赋值</h2> <ul><li><strong>初始化</strong>：在进行定义的时候，给它值是初始化</li> <li><strong>赋值</strong>：定义之后，换一行或多行，才给它值，是赋值</li></ul> <blockquote><p>引申到C++：</p></blockquote> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>C++中在class的初始化列表中有的必须写：
1、const常量，原因是必须初始化，一旦初始化就不能修改了，也就是不能重新赋值
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><ul><li>第4节、数组的不完全初始化辅助理解上述区别</li> <li>只有在数组定义时，给数组值才叫初始化</li> <li><strong>定义</strong>过后，再给数组值叫赋值</li></ul> <h2 id="⏰c语言标准历史"><a href="#⏰c语言标准历史" class="header-anchor">#</a> ⏰C语言标准历史</h2> <blockquote><p>参考书籍：《<a href="https://book.douban.com/subject/26792521/" target="_blank" rel="noopener noreferrer">C Primer Plus<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>》</p></blockquote> <ul><li>本文将讲解C语言各种标准，并且描述其特点。</li> <li>用处：帮助在开发中了解编译器支持什么标准，<b>更好的分析可能的编译出错原因</b>，因为，有时候可能<code>因为当前编译器支持的标准不同</code>就会导致编译出错</li> <li>各种标准细说</li></ul> <h3 id="_1-标准k-r-c"><a href="#_1-标准k-r-c" class="header-anchor">#</a> 1.标准<code>K&amp;R C</code></h3> <ul><li>1978年，丹尼斯•里奇（Dennis Ritchie）和布莱恩•柯林汉（Brian Kernighan）合作出版了<b>《C程序设计语言》的第一版</b>。<b>书中介绍的C语言标准也被称作“K&amp;R C”</b>。</li></ul> <h3 id="_2-标准ansi-c、iso-c、c89、c90-（重点）"><a href="#_2-标准ansi-c、iso-c、c89、c90-（重点）" class="header-anchor">#</a> 2.标准ANSI C、ISO C、C89、C90  （重点）</h3> <blockquote><p>(目前，我们说的<b>标准C</b>指的一般就是ANSI C)</p> <p>典型用书:《C程序设计语言》的<font color="red">第二版</font></p></blockquote> <ul><li>随着C语言使用得越来越广泛，出现了许多新问题，人们日益强烈地要求对C语言进行标准化。1983年，<b>美国国家标准协会（ANSI）</b>组成了一个委员会，X3J11，为了创立 C 的一套标准。经过漫长而艰苦的过程，该标准于<b>1989年</b>完成，这个版本的语言经常被称作<b>ANSI C</b>，或有时称为<b>C89（为了区别C99）</b>。</li> <li>在<b>1990年</b>，ANSI C标准（带有<b>一些小改动</b>）被美国国家标准协会（ANSI）采纳为ISO/IEC 9899:1990。这个版本有时候称为<b>C90</b>或者<b>ISO C</b>。</li> <li>综上，通常情况下，我们不加非常严格的区分，ANSI C、ISO C、C89、C90可以看做是同一种标准。</li></ul> <p>传统C语言（K&amp;R C）到 ANSI/ISO标准C语言的<b>改进</b>包括：</p> <ul><li>增加了真正的标准库</li> <li>新的预处理命令与特性</li> <li>函数原型允许在函数申明中指定参数类型</li> <li>一些新的关键字，包括 const、volatile 与 signed  宽字符、宽字符串与字节多字符</li> <li>对约定规则、声明和类型检查的许多小改动与澄清</li></ul> <h3 id="_3-c99标准（2000）"><a href="#_3-c99标准（2000）" class="header-anchor">#</a> 3.C99标准（2000）</h3> <blockquote><ul><li>2000年3月，ANSI 采纳了 ISO/IEC 9899:1999 标准。这个标准通常指C99。</li> <li>C99新增了一些特性:</li></ul> <blockquote><ul><li>1)<b>支持不定长的数组（柔性数组）</b>，即数组长度可以在运行时决定。</li> <li>2)变量声明不必放在语句块的开头，for 语句<b>提倡写成 for(int i=0;i&lt;100;++i) 的形式</b>，即i 只在for 语句块内部有效</li> <li>3)初始化结构的时候允许对特定的元素赋值。</li> <li>4)允许编译器化简非常数的表达式。</li> <li>5)<b>取消了函数返回类型默认为 int 的规定。</b></li> <li>Tips：但是各个公司对C99的支持所表现出来的兴趣不同。当GCC和其它一些商业编译器支持C99的大部分特性的时候，微软和Borland却似乎对此不感兴趣，他们把更多的精力放在了C++上。</li></ul></blockquote></blockquote> <p>典型的会造成下面情况的发生：</p> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string">&lt;stdio.h&gt;</span></span>
<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
	<span class="token comment">// C99允许在for循环内定义循环变量，而ANSIC C（C89）不允许</span>
	<span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">int</span> i<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">;</span> i<span class="token operator">&lt;</span><span class="token number">10</span> <span class="token punctuation">;</span><span class="token operator">++</span>i<span class="token punctuation">)</span> 
	<span class="token punctuation">{</span>
		<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;%d&quot;</span><span class="token punctuation">,</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token punctuation">}</span>
	<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div><p>上面的语句，在ANSI C，是不能通过编译的。因为他不支付，编译后会显示：
<code>[Error] 'for' loop initial declarations are only allowed in C99 or C11 mode</code>
但是，从C99开始，就可以编译通过了。
gcc下用这个方式可以指定用C99标准编译：</p> <div class="language-bash line-numbers-mode"><pre class="language-bash"><code>gcc -std<span class="token operator">=</span>c99 test.c -o test.exe
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>Tips：</p> <blockquote><ul><li>1)另外，事实上，<b>不定长数组</b>的定义早在C的C99标准里就已经被提出，但是<b>从来都没在C++标准（C++98、C++03、C++11）里存在过</b>。因此，<b>G++支持不定长数组完全是因为它<font color="red" size="4">同时支持C99和C++</font>（对C99标准支持得最好的就是G++了）</b>，而VS不怎么支持C99标准那是人尽皆知的，也就理所当然不支持C99的不定长数组了。</li> <li>2)此外，目前没有编译器可以完全实现C99，而且<b>为了兼容性，在写C代码时，通常我们不会去用C99标准</b>，<b>编译器也是默认不使用C99</b>的，因此C语言的书里说不允许这样定义数组，也是可以理解的。而C++ primer里也这么说，那是因为它说的是事实，C++里根本就不支持不定长数组。</li> <li>3)大概也是因为如上的原因，所以，<font color="red" size="3">到目前为止，我们还是认为ANSI C才是标准C</font>。</li></ul></blockquote> <h3 id="_4-c11标准（2011）"><a href="#_4-c11标准（2011）" class="header-anchor">#</a> 4.C11标准（2011）</h3> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token operator">-</span> 在<span class="token number">2011</span>年<span class="token number">12</span>月，ANSI 采纳了 ISO<span class="token operator">/</span>IEC <span class="token number">9899</span><span class="token operator">:</span><span class="token number">2011</span> 标准。这个标准通常即C11，它是C程序语言的最新标准。
<span class="token operator">-</span> 与C99相比，C11有这些变化：

<span class="token operator">&gt;</span><span class="token operator">-</span> <span class="token number">1</span>）对齐处理：<span class="token function">alignof</span><span class="token punctuation">(</span>T<span class="token punctuation">)</span>返回T的对齐方式，<span class="token function">aligned_alloc</span><span class="token punctuation">(</span><span class="token punctuation">)</span>以指定字节和对齐方式分配内存，头文件<span class="token operator">&lt;</span>stdalign<span class="token punctuation">.</span>h<span class="token operator">&gt;</span>定义了这些内容。
<span class="token operator">&gt;</span><span class="token operator">-</span> <span class="token number">2</span>）<span class="token keyword">_Noreturn</span>：<span class="token keyword">_Noreturn</span>是个函数修饰符，位置在函数返回类型的前面，声明函数无返回值，有点类似于gcc的<span class="token keyword">__attribute__</span><span class="token punctuation">(</span><span class="token punctuation">(</span>noreturn<span class="token punctuation">)</span><span class="token punctuation">)</span>，后者在声明语句尾部。
<span class="token operator">&gt;</span><span class="token operator">-</span> <span class="token number">3</span>）<span class="token keyword">_Generic</span>：<span class="token keyword">_Generic</span>支持轻量级范型编程，可以把一组具有不同类型而却有相同功能的函数抽象为一个接口。
<span class="token operator">&gt;</span><span class="token operator">-</span> <span class="token number">4</span>）<span class="token keyword">_Static_assert</span><span class="token punctuation">(</span><span class="token punctuation">)</span>：<span class="token keyword">_Static_assert</span><span class="token punctuation">(</span><span class="token punctuation">)</span>，静态断言，在编译时刻进行，断言表达式必须是在编译时期可以计算的表达式，而普通的<span class="token function">assert</span><span class="token punctuation">(</span><span class="token punctuation">)</span>在运行时刻断言。
<span class="token operator">&gt;</span><span class="token operator">-</span> <span class="token number">5</span>）安全版本的几个函数：<span class="token function">gets_s</span><span class="token punctuation">(</span><span class="token punctuation">)</span>取代了<span class="token function">gets</span><span class="token punctuation">(</span><span class="token punctuation">)</span>，原因是后者这个I<span class="token operator">/</span>O函数的实际缓冲区大小不确定，以至于发生常见的缓冲区溢出攻击，类似的函数还有其它的。
<span class="token operator">&gt;</span><span class="token operator">-</span> <span class="token number">6</span>）<span class="token function">fopen</span><span class="token punctuation">(</span><span class="token punctuation">)</span>新模式：<span class="token function">fopen</span><span class="token punctuation">(</span><span class="token punctuation">)</span>增加了新的创建、打开模式“x”，在文件锁中比较常用。
<span class="token operator">&gt;</span><span class="token operator">-</span> <span class="token number">7</span>）匿名结构体、联合体。
<span class="token operator">&gt;</span><span class="token operator">-</span> <span class="token number">8</span>）多线程：头文件<span class="token operator">&lt;</span>threads<span class="token punctuation">.</span>h<span class="token operator">&gt;</span>定义了创建和管理线程的函数，新的存储类修饰符<span class="token keyword">_Thread_local</span>限定了变量不能在多线程之间共享。
<span class="token operator">&gt;</span><span class="token operator">-</span> <span class="token number">9</span>）<span class="token keyword">_Atomic</span>类型修饰符和头文件<span class="token operator">&lt;</span>stdatomic<span class="token punctuation">.</span>h<span class="token operator">&gt;</span>。
<span class="token operator">&gt;</span><span class="token operator">-</span> <span class="token number">10</span>）改进的Unicode支持和头文件<span class="token operator">&lt;</span>uchar<span class="token punctuation">.</span>h<span class="token operator">&gt;</span>。
<span class="token operator">&gt;</span><span class="token operator">-</span> <span class="token number">11</span>）<span class="token function">quick_exit</span><span class="token punctuation">(</span><span class="token punctuation">)</span>：又一种终止程序的方式，当<span class="token function">exit</span><span class="token punctuation">(</span><span class="token punctuation">)</span>失败时用以终止程序。
<span class="token operator">&gt;</span><span class="token operator">-</span> <span class="token number">12</span>）复数宏，浮点数宏。
<span class="token operator">&gt;</span><span class="token operator">-</span> <span class="token number">13</span>）time<span class="token punctuation">.</span>h新增timespec结构体，时间单位为纳秒，原来的timeval结构体时间单位为毫秒。 	
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br></div></div><h2 id="✅语法篇"><a href="#✅语法篇" class="header-anchor">#</a> ✅语法篇</h2> <h2 id="c和c-变量命名规则探讨？"><a href="#c和c-变量命名规则探讨？" class="header-anchor">#</a> C和C++变量命名规则探讨？🤔</h2> <p><strong>变量命名规则</strong></p> <ul><li>不能是C语言或者C++的标识符。</li> <li>区分大小写</li> <li>变量的第1个字符必须是大小写字母或者下划线。</li> <li>即，除去第1个字符之外的其他字符是大小写字母，下划线，或数字。</li></ul> <p><strong>疑问</strong>：为什么，第3点要求看上去这么奇怪？
为什么，不直接说，是直接由大小写字母，下划线，数字组成就好了，为何要强调第1个字符，不能是数字？
看上去，一点都不对称，没有美感</p> <p><strong>解释</strong>:</p> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>想象一下，定义这样一个变量
int 1=9;//变量名字，要是叫1，那么我们的程序，难道以后，我用1就是9？多尴尬

反观
char c='d';
char D='c';
这样的多好，原因是：
字符在C语言和C++中是有单引号''围着的
字符串是有双引号&quot;&quot;围着的

或许，创造者在变量名取名规则的时候，首先是考虑了
1)大小写字母，毕竟是人家母语，要是计算机语言和母语由类似之处，多好。
2)数字，毕竟，阿拉伯数字享誉全球。
3)下划线，ummm，或许是为了今后的下划线命名法？？？疑问。。

然后发现，前面那样int 1=9;这样奇怪的语句，就规则强化了
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br></div></div><p><strong>工程上主流的变量命名法</strong></p> <ul><li>下划线命名法（C语言软件设计师常用）</li> <li>驼峰命名法（Java软件设计师常用）</li> <li>帕斯卡命名法</li> <li>匈牙利名</li></ul> <h2 id="_01-switch语法⭐️"><a href="#_01-switch语法⭐️" class="header-anchor">#</a> 01.switch语法⭐️</h2> <ul><li><a href="https://www.nowcoder.com/questionTerminal/07016c63465442fe858a1f323eb3fa0e" target="_blank" rel="noopener noreferrer">switch(c)语句中，c不可以是什么类型（）<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token keyword">int</span>
<span class="token keyword">long</span>
<span class="token keyword">char</span>
<span class="token keyword">float</span>
    
选D <span class="token keyword">float</span>
    
这个题目很好
<span class="token keyword">switch</span>相当于枚举，<span class="token keyword">int</span> <span class="token keyword">long</span> <span class="token keyword">char</span>这些整型都是又穷个数的
<span class="token keyword">float</span>有无穷多个，因此不能用<span class="token keyword">float</span>类型

『我在C<span class="token operator">++</span>primer上面也看到，只要整型和<span class="token keyword">enum</span>』
    

此外，<span class="token keyword">enum</span>也不是构造类型，它是一个基本类型，
    我们可以将一个<span class="token keyword">enum</span>作为<span class="token keyword">switch</span>语句的表达式！！！『C<span class="token operator">++</span> primer』说的
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br></div></div><ul><li>switch语句判断条件可以接受的数据类型有哪些？</li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token keyword">int</span>
byte
<span class="token keyword">char</span>
<span class="token keyword">short</span>
都可以，但是byte不是C<span class="token operator">++</span>的。。。Java中好像有
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><h2 id="⭐️类型转换"><a href="#⭐️类型转换" class="header-anchor">#</a> ⭐️类型转换?</h2> <h4 id="（1）自动类型转换"><a href="#（1）自动类型转换" class="header-anchor">#</a> （1）自动类型转换</h4> <p>当运算符的两边出现不一致的类型时，会自动转换成较大的类型
大的意思是能表达的数的范围更大</p> <ul><li><code>char -&gt; short -&gt; int -&gt; long -&gt; long long</code></li> <li><code>int -&gt;float -&gt;double</code></li> <li>特殊：
<ul><li>1、对于printf，任意小于int的类型会被转换成int</li> <li>2、但是scanf不会，要输入short，需要<code>%hd</code>『注意事项』</li></ul></li></ul> <h4 id="（2）强制类型转换"><a href="#（2）强制类型转换" class="header-anchor">#</a> （2）强制类型转换</h4> <p>要把一个量强制转换成另一个类型（通常是较小的类型）</p> <p>注意，这时候的安全性，小的变量不总能表达大的量</p> <ul><li>只是从那个变量<strong>计算</strong>出了一个新的类型的值。它并不改变那个变量，无论是值还是类型都不改变</li></ul> <h2 id="✔️参加位运算的数据其类型不能是？"><a href="#✔️参加位运算的数据其类型不能是？" class="header-anchor">#</a> ✔️参加位运算的数据其类型不能是？</h2> <ul><li>牛客网<a href="https://www.nowcoder.com/test/question/done?tid=44308591&qid=80375#summary" target="_blank" rel="noopener noreferrer">传送门<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li> <li>无论是float  还是double,在内存中的存储分为三部分：符号位，指数位，尾数位；位运算符对它们没有意义</li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code>网上找的：
按位运算是对字节或字中的实际位进行检测、设置或移位<span class="token punctuation">,</span> 它只适用于字符型和整数型变量以及它们的变体<span class="token punctuation">,</span> 对其它数据类型不适用。
    
loat、<span class="token keyword">double</span>、<span class="token keyword">long</span> <span class="token keyword">double</span>等类型不允许直接进行位与操作符啊，可用间接的方法变通，如<span class="token keyword">float</span>取地址（也是<span class="token operator">&amp;</span>符号）转换为<span class="token keyword">unsigned</span> <span class="token keyword">int</span>类型，再用取值操作符（<span class="token operator">*</span>），这样编译器会以为是<span class="token keyword">unsigned</span> <span class="token keyword">int</span>类型。
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><h2 id="_02-常用ascii码值记忆法"><a href="#_02-常用ascii码值记忆法" class="header-anchor">#</a> 02.常用ASCII码值记忆法</h2> <ul><li><p>参考牛客网+自我思考补充</p></li> <li><p>或许以为这个不用记忆，但是在编码的时候，这个还是用到了，而且某些学校考试是会考的。</p></li> <li><p><code>'\0'</code>   //ASCII是0</p></li> <li><p><code>' '</code>   //空格，ASCII是32</p></li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token comment">//上面一组已经记熟了。</span>
    
<span class="token string">'0'</span><span class="token comment">//ASCII是48</span>
<span class="token string">'A'</span><span class="token comment">//ASCII是65</span>
<span class="token string">'a'</span><span class="token comment">//ASCII是97</span>
<span class="token number">486</span> <span class="token number">597</span>
死<span class="token number">86</span>，误久期<span class="token punctuation">(</span>si ba l<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
此外，<span class="token number">486</span><span class="token operator">+</span><span class="token number">111</span><span class="token operator">=</span><span class="token number">597</span>
    
常用性质：
<span class="token number">1</span>、空串等于a减A，也就是<span class="token string">'a'</span><span class="token operator">-</span><span class="token string">'A'</span><span class="token operator">=</span><span class="token number">32</span><span class="token operator">=</span><span class="token string">' '</span> <span class="token comment">//编程的时候有人这么用</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div><h2 id="_03-数组的『初始化方式』⭐️"><a href="#_03-数组的『初始化方式』⭐️" class="header-anchor">#</a> 03.数组的『初始化方式』⭐️</h2> <ul><li>C语言和C++中数组的初始化</li></ul> <h3 id="_3-1-问题由来"><a href="#_3-1-问题由来" class="header-anchor">#</a> 3.1.问题由来</h3> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token keyword">int</span> a<span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">]</span><span class="token operator">=</span><span class="token punctuation">{</span><span class="token number">0</span><span class="token punctuation">}</span> 把数组全部初始化为<span class="token number">0</span>
<span class="token keyword">int</span> a<span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">]</span><span class="token operator">=</span><span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">}</span> 把数组全部初始化为<span class="token number">1</span>，为什么却失败了呢？
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><ul><li><font style="background:yellow;"><strong>数组的几种初始化方式</strong></font></li></ul> <h3 id="_3-2-完全初始化"><a href="#_3-2-完全初始化" class="header-anchor">#</a> 3.2.完全初始化</h3> <ul><li><code>完全初始化（completely initialized）</code>：给每个元素初始化</li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token keyword">int</span> a<span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">]</span><span class="token operator">=</span><span class="token punctuation">{</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> a<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token operator">=</span><span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><h3 id="_2-3-完全不初始化（uninitialized）"><a href="#_2-3-完全不初始化（uninitialized）" class="header-anchor">#</a> 2.3.完全不初始化（uninitialized）</h3> <p><code>int a[5];</code>
注意：不进行显式初始化的情况下：</p> <blockquote><ul><li><b>未初始化的</b>全局变量以及静态变量的初始均为0（因为他们都存在.bss段，默认初始化为0）</li> <li><b>未初始化的</b>局部变量（自动变量）随机（其实也不叫随机，要是你能够精确的设计上一个释放这块内存的地方存了什么值，你就能自行控制，局部变量处于栈区，其数值是当时内存中的值。）</li></ul></blockquote> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string">&lt;stdio.h&gt;</span></span>
<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
	<span class="token keyword">int</span> bb<span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
	<span class="token keyword">int</span> i<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">;</span>
	<span class="token keyword">for</span><span class="token punctuation">(</span> <span class="token punctuation">;</span> i<span class="token operator">&lt;</span><span class="token number">5</span> <span class="token punctuation">;</span> <span class="token operator">++</span>i<span class="token punctuation">)</span>
	<span class="token punctuation">{</span>
		<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;%d\n&quot;</span> <span class="token punctuation">,</span>bb<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token punctuation">}</span>
	<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//output:(不确定的)</span>
<span class="token comment">//6487736</span>
<span class="token comment">//4202350</span>
<span class="token comment">//4202256</span>
<span class="token comment">//0</span>
<span class="token comment">//29</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br></div></div><div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string">&lt;stdio.h&gt;</span></span>

<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span> <span class="token punctuation">)</span>
<span class="token punctuation">{</span> 
	<span class="token keyword">static</span> <span class="token keyword">int</span> bb<span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
	<span class="token keyword">int</span> i<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">;</span>
	<span class="token keyword">for</span><span class="token punctuation">(</span> <span class="token punctuation">;</span> i<span class="token operator">&lt;</span><span class="token number">5</span> <span class="token punctuation">;</span> <span class="token operator">++</span>i<span class="token punctuation">)</span>
	<span class="token punctuation">{</span>
		<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;%d\n&quot;</span> <span class="token punctuation">,</span>bb<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token punctuation">}</span>
	
	<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//output:</span>
<span class="token comment">//0</span>
<span class="token comment">//0</span>
<span class="token comment">//0</span>
<span class="token comment">//0</span>
<span class="token comment">//0</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br></div></div><div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string">&lt;stdio.h&gt;</span></span>
<span class="token keyword">int</span> bb<span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span> <span class="token punctuation">)</span>
<span class="token punctuation">{</span> 
	
	<span class="token keyword">int</span> i<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">;</span>
	<span class="token keyword">for</span><span class="token punctuation">(</span> <span class="token punctuation">;</span> i<span class="token operator">&lt;</span><span class="token number">5</span> <span class="token punctuation">;</span> <span class="token operator">++</span>i<span class="token punctuation">)</span>
	<span class="token punctuation">{</span>
		<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;%d\n&quot;</span> <span class="token punctuation">,</span>bb<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token punctuation">}</span>
	
	<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//output:</span>
<span class="token comment">//0</span>
<span class="token comment">//0</span>
<span class="token comment">//0</span>
<span class="token comment">//0</span>
<span class="token comment">//0</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br></div></div><h3 id="_2-4-不完全初始化"><a href="#_2-4-不完全初始化" class="header-anchor">#</a> 2.4.不完全初始化</h3> <ul><li><code>不完全初始化（Partly initialized）</code>（即：部分初始化）</li></ul> <p><code>int a[5]={0,1,2};</code>
K&amp;R C语言中是这样阐述：</p> <blockquote><ul><li><b>如果初始化表达式的个数比数组元素数少，则对外部变量，静态变量和自动变量来说，没有初始化表达式的元素将被初始化为0。</b>（至于为什么是初始化为0而不是其他的，原因是.bss的实现机制）</li> <li>如果初始化表达式的个数比数组元素数多,则是错误的。
所以，上面数组，前三个元素被初始化为0，1，2，后两个元素被初始化为0。</li></ul></blockquote> <p>实际上，int a[5]={0};属于不完全初始化，先把第一个元素初始化为0，由于初始化元素个数不够，所以剩余的元素按照规则被初始化为0，虽然都是0，但是它和后面那些0的意义不同（此0非彼0）</p> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string">&lt;stdio.h&gt;</span></span>

<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span> <span class="token punctuation">)</span>
<span class="token punctuation">{</span> 
	<span class="token keyword">int</span> bb<span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">]</span><span class="token operator">=</span><span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
	<span class="token keyword">int</span> i<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">;</span>
	<span class="token keyword">for</span><span class="token punctuation">(</span> <span class="token punctuation">;</span> i<span class="token operator">&lt;</span><span class="token number">5</span> <span class="token punctuation">;</span> <span class="token operator">++</span>i<span class="token punctuation">)</span>
	<span class="token punctuation">{</span>
		<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;%d\n&quot;</span> <span class="token punctuation">,</span>bb<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token punctuation">}</span>
	
	<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//output:</span>
<span class="token comment">//1</span>
<span class="token comment">//0</span>
<span class="token comment">//0</span>
<span class="token comment">//0</span>
<span class="token comment">//0</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br></div></div><div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string">&lt;stdio.h&gt;</span></span>

<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span> <span class="token punctuation">)</span>
<span class="token punctuation">{</span> 
	<span class="token keyword">static</span> <span class="token keyword">int</span> bb<span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">]</span><span class="token operator">=</span><span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
	<span class="token keyword">int</span> i<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">;</span>
	<span class="token keyword">for</span><span class="token punctuation">(</span> <span class="token punctuation">;</span> i<span class="token operator">&lt;</span><span class="token number">5</span> <span class="token punctuation">;</span> <span class="token operator">++</span>i<span class="token punctuation">)</span>
	<span class="token punctuation">{</span>
		<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;%d\n&quot;</span> <span class="token punctuation">,</span>bb<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token punctuation">}</span>
	
	<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//output:</span>
<span class="token comment">//1</span>
<span class="token comment">//0</span>
<span class="token comment">//0</span>
<span class="token comment">//0</span>
<span class="token comment">//0</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br></div></div><h3 id="_2-5-假装初始化（我编的-）"><a href="#_2-5-假装初始化（我编的-）" class="header-anchor">#</a> 2.5.假装初始化（我编的..）</h3> <ul><li>其实这种初始化方式也是『不完全初始化』的一种</li> <li>但是在ICPC中，很多人这么写</li> <li><code>int a[10]={};</code></li> <li>编译器自动将<strong>所有元素置0</strong></li></ul> <h2 id="_04-union『c语言中』"><a href="#_04-union『c语言中』" class="header-anchor">#</a> 04.union『C语言中』</h2> <blockquote><p>又叫：共用体（联合）</p> <p>吐槽：名字真多</p></blockquote> <h3 id="_1-union"><a href="#_1-union" class="header-anchor">#</a> 1.union</h3> <p>union中文翻译为“<code>联合</code>”（又称<code>共用体</code>）</p> <ul><li>吐槽—没事取这么多名字干啥<code>...</code>（好吧，其实是翻译，每个人有自己的翻译方式）</li></ul> <blockquote><ul><li>个人倾向于用共用体的名字，因为union共用内存的特点从名字就能直观的看出来，但是也有书上写成联合，所以，我也从各种地方搜集，发现一个还算说得过去的说明，叫“联合”显示union特点的解释。</li></ul></blockquote> <ul><li>联合：大家联合起来使用同一个空间</li></ul> <h3 id="_2-union的特点"><a href="#_2-union的特点" class="header-anchor">#</a> 2.union的特点</h3> <ul><li><b>特点</b>：使用同一个空间（tips：共用体也有<code>内存对齐</code>！）</li> <li>你用了，我就不能用了（除非你想使坏，把前面别人要用的给覆盖掉）</li> <li>PS:共用体，其实表明了计算机学科一个很重要的性质，那就是，其实数据都是0和1，至于为什么后面会有字符型，整型，图片，音频什么的，完全是对这些比特位的解释的不用导致的情况，所以，同样比特的可以解释是1首歌，也可以解释是一张图片（当然，需要你解释这些比特的算法正确）</li> <li><strong>常用场景</strong> <ul><li>1）这么节省内存，那嵌入式必须首先用起（要是两个不会同时使用的话）</li> <li>2）网络传输：通信中的数据包会用到共用体，因为不知道对方会发送一个什么过来，用共用体就简单了，定义几种格式的包，收到包之后就可以直接根据包的格式取出数据。</li></ul></li></ul> <h2 id="_05-位段（也叫位域）bit-field"><a href="#_05-位段（也叫位域）bit-field" class="header-anchor">#</a> 05.位段（也叫位域）<code>Bit field</code></h2> <ul><li>一种<strong>特殊</strong>的<code>结构体struct</code></li></ul> <h3 id="_1、引言"><a href="#_1、引言" class="header-anchor">#</a> 1、引言</h3> <p>我们在做单片机的时候。微控制单元（Microcontroller Unit；MCU），又称单片微型计算机（Single Chip Microcomputer ）或者单片机。经常会告诉你第几个比特是什么什么叫停止比特啥的。如何操作呢？后面的数字是说，这个成员占几个比特。其实这种手法在C语言中的实现就可以用我们现在要讲的位段方式。当然，位段并不是这些偏底层的程序实现的唯一应用场景，我们还能将这些用于网络通信等。</p> <h3 id="_2、语法"><a href="#_2、语法" class="header-anchor">#</a> 2、语法</h3> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token keyword">struct</span> <span class="token class-name">test</span>
	<span class="token punctuation">{</span>
		<span class="token keyword">unsigned</span> <span class="token keyword">int</span> a<span class="token operator">:</span><span class="token number">1</span><span class="token punctuation">;</span>
		<span class="token keyword">unsigned</span> <span class="token keyword">int</span> b<span class="token operator">:</span><span class="token number">2</span><span class="token punctuation">;</span>
		<span class="token keyword">unsigned</span> <span class="token keyword">int</span> c<span class="token operator">:</span><span class="token number">4</span><span class="token punctuation">;</span>
		<span class="token keyword">int</span> tt<span class="token operator">:</span> <span class="token number">11</span><span class="token punctuation">;</span>
	<span class="token punctuation">}</span>demo<span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><p>特点：
编译器会安排其中的位的排列，<code>不具有可移植性</code>
当所需的位超过一个int时会采用多个int</p> <h3 id="_3、位段的特点和『内存对齐』"><a href="#_3、位段的特点和『内存对齐』" class="header-anchor">#</a> 3、位段的特点和『内存对齐』</h3> <p>对于位域的定义，有以下几点说明：</p> <ul><li>（1）一个位域必须存储在同一个字节中，不能跨两个字节。如一个字节所剩空间不够存放另一位域时，应从下一单元起存放该位域。也可以有意使某位域从下一单元开始。</li></ul> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token keyword">struct</span> <span class="token class-name">wy</span>
<span class="token punctuation">{</span>
   <span class="token keyword">unsigned</span> a<span class="token operator">:</span><span class="token number">6</span><span class="token punctuation">;</span>
   <span class="token keyword">unsigned</span> <span class="token number">0</span><span class="token punctuation">;</span>     <span class="token comment">//空域</span>
   <span class="token keyword">unsigned</span> b<span class="token operator">:</span><span class="token number">4</span><span class="token punctuation">;</span>   <span class="token comment">//从一单元开始存放</span>
   <span class="token keyword">unsigned</span> c<span class="token operator">:</span><span class="token number">4</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//在这个位域定义中，a占第一字节的6位，后2位填0表示不使用，</span>
<span class="token comment">//b从第二字节开始，占用4位，c占用4位。</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><ul><li>（2）由于位域不允许跨两个字节，因此位域的长度不能大于一个字节的长度，也就是不能超过8位二进位。</li> <li>（3）位域可以无位域名，这时它只用来填充或调整位置。无名的位域是不能使用的。</li></ul> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token keyword">struct</span> <span class="token class-name">wk</span>
<span class="token punctuation">{</span>
   <span class="token keyword">int</span> a<span class="token operator">:</span><span class="token number">1</span><span class="token punctuation">;</span>
   <span class="token keyword">int</span> <span class="token operator">:</span><span class="token number">2</span><span class="token punctuation">;</span>     <span class="token comment">//不能使用</span>
   <span class="token keyword">int</span> b<span class="token operator">:</span><span class="token number">3</span><span class="token punctuation">;</span>
   <span class="token keyword">int</span> c<span class="token operator">:</span><span class="token number">2</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><p>从以上述分析可以看出，位域可以看做是一种结构类型，其特点是成员均<b>按二进位分配</b></p> <h2 id="_06-c语言常量和c-常量"><a href="#_06-c语言常量和c-常量" class="header-anchor">#</a> 06.C语言常量和C++常量</h2> <p><font size="3" style="background:yellow;">如果想要真正深入学懂C语言，请使用Linux测试所有以前教材上看不懂的内容，而不是使用Windows，从本文的字符常量，就知道原因了</font></p> <ul><li>常量：为固定值，在程序执行期间不会改变</li> <li>可以是任何的基本数据类型，如，整型数字，浮点数字，字符，字符串，布尔值</li></ul> <h3 id="_6-1-整数常量"><a href="#_6-1-整数常量" class="header-anchor">#</a> 6.1.整数常量</h3> <ul><li>注意：整数常量也可以带“后缀”</li></ul> <table><thead><tr><th>前缀指定“基数”</th> <th>后缀是U和L的组合</th></tr></thead> <tbody><tr><td>1）0x或0X表示16进制</td> <td>1）U表示无符号整数（unsigned）</td></tr> <tr><td>2）0表示8进制</td> <td>2）L表示长整数（long）</td></tr> <tr><td>3）其余默认为10进制</td> <td>3）U和L可大，小写（不区分！）</td></tr> <tr><td></td> <td>4）U和L的顺序任意</td></tr></tbody></table> <p>下面都是合法的</p> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token number">0xFFUL</span>	<span class="token comment">//合法！</span>
<span class="token number">0xFFLU</span>	<span class="token comment">//合法！</span>
<span class="token number">0xffLU</span>	<span class="token comment">//合法！</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><h3 id="_6-2-浮点常量"><a href="#_6-2-浮点常量" class="header-anchor">#</a> 6.2.浮点常量</h3> <p>浮点常量：由整数部分，小数点，小数部分和指数部分组成</p> <ul><li>1）小数形式表示时：必须包含整数部分或小数部分或两种都有</li> <li>2）用指数形式时：必须包含小数点或指数或两者都有
<ul><li>带符号的指数是用e或E引入的！</li></ul></li></ul> <p>合法的如下</p> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token number">3.145</span>	<span class="token comment">//合法，小数形式</span>
<span class="token number">312E5</span>	<span class="token comment">//合法，指数形式</span>
<span class="token number">31415E-5L</span>	<span class="token comment">//合法，指数形式，而31415E-5l   也可以（注意，浮点常量和整数常量规则结合了）</span>
<span class="token number">312e3</span>	<span class="token comment">//合法，指数形式</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><h3 id="_6-3-字符常量-a"><a href="#_6-3-字符常量-a" class="header-anchor">#</a> 6.3.字符常量'a'</h3> <p>字符常量：是括在单引号中，如果常量是以L<font style="background:yellow;">（仅当大写时）开头</font>，则表示它是一个<strong>宽</strong>字符常量（例如 <code>L'x'</code> ）</p> <p>字符常量可以是：</p> <ul><li><p>1）一个普通的字符，例如 <code>'x'</code></p></li> <li><p>2）一个<strong>转义序列</strong>，例如  <code>'\t'</code></p></li> <li><p>3）一个通用的字符，例如  <code>'\u02C0'</code> <font style="background:yellow;">不知道这是啥？我以前做的笔记，自己咋看不懂了，，</font></p></li></ul> <table><thead><tr><th>转义序列码</th> <th>效果</th></tr></thead> <tbody><tr><td>'\a'</td> <td>警报铃声（打开电脑喇叭，自己听，响一下）</td></tr> <tr><td>'\b'</td> <td>退格键（注意，“此退格键非彼退格键”，也就是说，和我们键盘上的不一样！）</td></tr> <tr><td>'\f'</td> <td>换页键（请在Linux下测试这些，在Windows上，这些表现很不一样）</td></tr> <tr><td>‘\r’</td> <td>回车（注意，“此回车键非彼回车键”，也就是说，和我们键盘上的不一样！）</td></tr> <tr><td>'\t'</td> <td></td></tr> <tr><td></td> <td></td></tr> <tr><td></td> <td></td></tr></tbody></table> <h4 id="（1）测试-b"><a href="#（1）测试-b" class="header-anchor">#</a> （1）测试'\b'</h4> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;aaa\b&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;aaa&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
上面，似乎输出内容一样？
    是的，但是意义不一样，而且请观察光标位置
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><table><thead><tr><th>代码</th> <th>效果</th></tr></thead> <tbody><tr><td><code>printf(&quot;aaa\b&quot;);</code></td> <td>aa<u>a</u>      （注意，光标在最后一个a）</td></tr> <tr><td><code>printf(&quot;aaa&quot;);</code></td> <td>aaa<u>光标</u>      （注意，光标在最后一个a之后）</td></tr> <tr><td>测试<code>printf(&quot;aaa\b1&quot;);</code></td> <td>aa1<u>光标</u>       （观察完上面，再测试这个，应该懂了）</td></tr></tbody></table> <h3 id="_6-4-字符串常量-a"><a href="#_6-4-字符串常量-a" class="header-anchor">#</a> 6.4.字符串常量<code>&quot;a&quot;</code></h3> <h3 id="_6-5-布尔型常量"><a href="#_6-5-布尔型常量" class="header-anchor">#</a> 6.5.布尔型常量</h3> <h2 id="_07-c语言static成员"><a href="#_07-c语言static成员" class="header-anchor">#</a> 07.C语言<code>static</code>成员</h2> <ul><li>静态成员存在于<strong>内存</strong>，非静态成员需要实例化才会分配内存</li> <li>（注意，也就是在虚拟内存空间中，表示的是<code>.bss</code>和<code>.data段</code>中）</li> <li>非静态成员的生存期决定于该类的生存期，而静态成员生存期则与程序生命期相同</li></ul> <h2 id="🍀详解c语言中const"><a href="#🍀详解c语言中const" class="header-anchor">#</a> 🍀详解C语言中const</h2> <p><font color="red" size="4">C语言中的const修饰的变量，叫做常变量（奇怪的名字）</font></p> <h3 id="_1-概述："><a href="#_1-概述：" class="header-anchor">#</a> 1.概述：</h3> <p>Q：C语言中，const关键字限定一个变量为只读，但它是真正意义上的只读吗？
A：C语言中的并不是的！const虽说是constant的简写，是不变的意思。
但在C语言中，const并不是说它修饰常量，而是说它限定一个变量为只读。</p> <blockquote><ul><li><b>C语言</b>中，const关键字修饰的变量并<b>非真正意义完完全全的只读</b>！</li> <li>（难怪叫<strong>常变量</strong>,<font color="pink">因为C语言中const就没有把这个变量变成常量！）</font></li></ul></blockquote> <p>Tips：<b>C++</b>中则对const关键字进行了加强，使得真的变成了常量（详情见C++中const详解）
所以，<b>我们常说C++中const修饰的变量，叫做const常量。</b></p> <h3 id="_2-基本用法："><a href="#_2-基本用法：" class="header-anchor">#</a> 2.基本用法：</h3> <h4 id="（1）修饰普通变量"><a href="#（1）修饰普通变量" class="header-anchor">#</a> （1）修饰普通变量</h4> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token keyword">const</span> <span class="token keyword">int</span> num <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> <span class="token comment">//与int const num等价</span>
num <span class="token operator">=</span> <span class="token number">9</span><span class="token punctuation">;</span>  <span class="token comment">//编译错误，不可再次修改</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><p>DevC++的C语言编译器编译：
<code>[Error] assignment of read-only variable 'NUM'</code>
解释：
由于使用了const修饰NUM，使得NUM为只读，因此尝试对NUM再次赋值的操作是非法的，编译器将会报错。所以，如果需要使用const修饰一个变量，那么它只能在开始声明时就赋值，否则用<b>一般做法</b>在后面就没有机会了（比如，特别的，C语言中可以用指针间接改变）。</p> <h4 id="（2）修饰数组"><a href="#（2）修饰数组" class="header-anchor">#</a> （2）修饰数组</h4> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token comment">//使用const关键字修饰数组，使其元素不允许被改变</span>
<span class="token comment">//试图修改arr的内容的操作是非法的，编译器将会报错</span>
<span class="token keyword">const</span> <span class="token keyword">int</span> arr<span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">//与int const arr[]等价</span>
arr<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token comment">//编译错误</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><p>DevC++的C语言编译：
<code>[Error] assignment of read-only location 'arr[2]'</code></p> <h4 id="（3）修饰指针（重点）"><a href="#（3）修饰指针（重点）" class="header-anchor">#</a> （3）修饰指针（重点）</h4> <p>先补充</p> <blockquote><ul><li>下面这两种写法是等效的的！</li></ul> <blockquote><ul><li>const int a=3;</li> <li>int const a=3;</li></ul></blockquote></blockquote> <p>修饰指针的主要有以下几种情况：
1）const 修饰 *p，<b>指向的对象只读</b>，指针的指向可变:</p> <blockquote><ul><li>常量指针——指向常量的指针，顾名思义，就是指针指向的是常量，即它不能指向变量，它指向的内容不能被改变，不能通过指针来修改它指向的内容，但是指针自身不是常量，它自身的值可以改变，从而指向另一个常量。</li></ul></blockquote> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token keyword">int</span> a <span class="token operator">=</span> <span class="token number">9</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> b <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> <span class="token keyword">int</span> <span class="token operator">*</span>p <span class="token operator">=</span> <span class="token operator">&amp;</span>a<span class="token punctuation">;</span><span class="token comment">//p是一个指向int类型的const值,与int const *p等价</span>
<span class="token operator">*</span>p <span class="token operator">=</span> <span class="token number">11</span><span class="token punctuation">;</span>    <span class="token comment">//编译错误，指向的对象是只读的，不可通过p进行改变</span>
p <span class="token operator">=</span> <span class="token operator">&amp;</span>b<span class="token punctuation">;</span>     <span class="token comment">//合法，改变了p的指向</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><p>换句话说更加准确：指针P是指向<code>const int *</code></p> <p>这里为了便于理解，可认为const修饰的是<em>p，通常使用</em>对指针进行解引用来访问对象，因而该对象是只读的。</p> <ul><li>此处补充——《C专家编程》书中的一段）</li></ul> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token keyword">char</span> <span class="token operator">*</span>cp<span class="token punctuation">;</span>
<span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>Ccp<span class="token punctuation">;</span>
ccp <span class="token operator">=</span> Cp<span class="token punctuation">;</span>
<span class="token comment">//左操作数是一个指向有const限定符的char的指针。</span>
<span class="token comment">//右操作数是一个指向没有限定符的char的指针。</span>
<span class="token comment">//char类型与char类型是相容的，左操作数所指向的类型具有右操作数所指向类型的限定符(无)，再加上自身的限定符(const)。</span>
<span class="token comment">//注意，反过来就不能进行赋值。试试下而的代码:</span>
cp <span class="token operator">=</span> ccp<span class="token punctuation">;</span>
<span class="token comment">/*结果产生编译警告*/</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><p>解释：</p> <ul><li><code>const char *ccp;</code>//表示我保证，我不会去改变我指向的那个对象</li> <li><code>char *cp;</code>//表示我可以改变我指向的那个对象</li> <li>我们可以，想想一下一个场景来理解ccp和cp的相互赋值的合法性</li></ul> <blockquote><ul><li>ccp=cp;//表示，cp告诉ccp说，我给你的对象，我可以改变，我赋值给你，你要是想改也可以。ccp说,我是有原则的，我的原则就是，我不会去改变我指向的那个对象（相容），ccp说，行，随你。</li> <li>cp=ccp;//表示，ccp告诉cp，我给你的对象，我可舍不得改了，我赋值给你，你可不能改，ccp说，我也是有原则的，我就要改，而它一改，编译器就阻止它说，你这样不行，侵犯了ccp的原则。</li></ul></blockquote> <ol start="2"><li>const修饰p，指向的对象可变，<b>指针的指向不可变</b>：</li></ol> <blockquote><ul><li>指针常量——指针本身是常量。它指向的地址是不可改变的，但地址里的内容可以通过指针改变。它指向的地址将伴其一生，直到生命周期结束。有一点需要注意的是，指针常量在定义时必须同时赋初值。</li></ul></blockquote> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token keyword">int</span> a <span class="token operator">=</span> <span class="token number">9</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> b <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token operator">*</span> <span class="token keyword">const</span> p <span class="token operator">=</span> <span class="token operator">&amp;</span>a<span class="token punctuation">;</span><span class="token comment">//p是一个const指针</span>
<span class="token operator">*</span>p <span class="token operator">=</span> <span class="token number">11</span><span class="token punctuation">;</span>    <span class="token comment">//合法，</span>
p <span class="token operator">=</span> <span class="token operator">&amp;</span>b<span class="token punctuation">;</span>     <span class="token comment">//编译错误，p是一个const指针，只读，不可变</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><ol start="3"><li>指针不可改变指向，指向的内容也不可变</li></ol> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token keyword">int</span> a <span class="token operator">=</span> <span class="token number">9</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> b <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> <span class="token keyword">int</span> <span class="token operator">*</span> <span class="token keyword">const</span> p <span class="token operator">=</span> <span class="token operator">&amp;</span>a<span class="token punctuation">;</span><span class="token comment">//p既是一个const指针，同时也指向了int类型的const值</span>
<span class="token operator">*</span>p <span class="token operator">=</span> <span class="token number">11</span><span class="token punctuation">;</span>    <span class="token comment">//编译错误，指向的对象是只读的，不可通过p进行改变</span>
p <span class="token operator">=</span> <span class="token operator">&amp;</span>b<span class="token punctuation">;</span>     <span class="token comment">//编译错误，p是一个const指针，只读，不可变</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><p>小结：
const放在<em>的左侧，限定了该指针指向的对象是只读的；
const放在</em>的右侧，限定了指针本身是只读的，即不可变的。</p> <ul><li>记忆法：</li></ul> <p><font style="background:pink;">const右边修饰谁，就说明谁是不可变的</font></p> <p>解释：</p> <ul><li>首先我们去掉类型说明符，查看const右边修饰的内容，上面三种情况去掉类型说明符int之后，如下：</li> <li><code>const int *p</code>; //修饰*p，指针p指向的对象<code>*p</code>不可变</li> <li><code>int * const p;</code> //修饰p，指针p本身不可变</li> <li><code>const int * const p</code>; //第一个修饰了<code>*p</code>，第二个修饰了<code>p</code>，两者都不可变</li> <li>此外，这种记忆法，还能帮助记忆先前那两个等价的形式：</li></ul> <blockquote><ul><li>const int NUM = 10; 	//与int const NUM等价</li> <li>const int *p  = &amp;a;		//与int const *p等价</li> <li>const int arr[] = {0,0,2,3,4}; 	//与int const arr[]等价</li></ul></blockquote> <h4 id="（4）修饰函数形参（重点）"><a href="#（4）修饰函数形参（重点）" class="header-anchor">#</a> （4）修饰函数形参（重点）</h4> <p><b>（重点，在函数接口，控制指针只做输入/<em>in</em>/）</b></p> <p>实际上，为我们可以经常发现const关键字的身影，例如很多库函数的声明：</p> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token keyword">char</span> <span class="token operator">*</span> <span class="token function">strncpy</span><span class="token punctuation">(</span><span class="token keyword">char</span> <span class="token operator">*</span>dest<span class="token punctuation">,</span> <span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>src<span class="token punctuation">,</span> <span class="token class-name">size_t</span> n<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//字符串拷贝函数</span>
<span class="token keyword">int</span>  <span class="token operator">*</span> <span class="token function">strncmp</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>s1<span class="token punctuation">,</span> <span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>s2<span class="token punctuation">,</span> <span class="token class-name">size_t</span> n<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//字符串比较函数</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><p>观察一个例子：</p> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token comment">//test.c</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string">&lt;stdio.h&gt;</span></span>
<span class="token keyword">void</span> <span class="token function">myPrint</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>str<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">void</span> <span class="token function">myPrint</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>str<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    str<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">'H'</span><span class="token punctuation">;</span>
    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;my print:%s\n&quot;</span><span class="token punctuation">,</span>str<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">char</span> str<span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">&quot;hello world&quot;</span><span class="token punctuation">;</span>
    <span class="token function">myPrint</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br></div></div><p>此例子中，我们不希望myPrint函数修改传入的字符串内容，因此入参使用了const限定符，表明传入的字符串是只读的，因此，如果myPrint函数内部如果尝试对str进行修改，将会报错:
<code>error: assignment of read-only location ‘*str’str[0] = 'H';</code></p> <p><b>工程常用做法</b>：</p> <ul><li>我们在编码过程中，如果确定传入的指针参数仅用于访问数据，那么应该将其声明为一个指向const限定类型的指针，避免函数内部对数据进行意外地修改!</li></ul> <h4 id="（5）修饰全局变量"><a href="#（5）修饰全局变量" class="header-anchor">#</a> （5）修饰全局变量</h4> <p>我们知道，使用全局变量是一种不安全的做法，因为程序的任何部分都能够对全局数据进行修改。而如果对全局变量增加const限定符（假设该全局数据不希望被修改），就可以避免被程序其他部分修改。这里有两种使用方式。
1）第一种，在a文件中定义，其他文件中使用外部声明，例如：</p> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token comment">//a.h</span>
<span class="token keyword">const</span> <span class="token keyword">int</span> ARR<span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token number">5</span><span class="token punctuation">,</span><span class="token number">6</span><span class="token punctuation">,</span><span class="token number">7</span><span class="token punctuation">,</span><span class="token number">8</span><span class="token punctuation">,</span><span class="token number">9</span><span class="token punctuation">}</span><span class="token punctuation">;</span>  <span class="token comment">//定义int数组</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token comment">//b.c</span>
<span class="token keyword">extern</span> <span class="token keyword">const</span> <span class="token keyword">int</span> ARR<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>   <span class="token comment">//注意，这里不能再对ARR进行赋值</span>
<span class="token comment">//后面可以使用ARR</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>2）第二种，在a文件中定义，并使用static修饰，b文件包含a文件，例如：</p> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token comment">//a.h</span>
<span class="token keyword">static</span> <span class="token keyword">const</span> <span class="token keyword">int</span> ARR<span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token number">5</span><span class="token punctuation">,</span><span class="token number">6</span><span class="token punctuation">,</span><span class="token number">7</span><span class="token punctuation">,</span><span class="token number">8</span><span class="token punctuation">,</span><span class="token number">9</span><span class="token punctuation">}</span><span class="token punctuation">;</span>  <span class="token comment">//定义int数组</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token comment">//b.c</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string">&lt;a.h&gt;</span></span>
<span class="token comment">//后面可以使用ARR</span>
注意，这里必须使用<span class="token keyword">static</span>修饰，否则多个文件包含导致编译会出现重复定义的错误。可以尝试一下。（为什么？因为，<span class="token keyword">static</span>修饰的变量，要是初始化了是放在<span class="token punctuation">.</span>data段的，而不是栈区）
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><p>易错点：</p> <ul><li><font style="background:pink;">Q：C语言中const修饰的变量是真正的只读吗？</font></li> <li><font style="background:pink;">A：C语言const修饰的变量，可以被间接修改！</font></li></ul> <p>在C语言中，const变量只不过是修饰该变量名，它并不能使内存变为只读。也就是说，我们不能通过变量名再去操作这块内存。但是可以通过其它方法，如指针，通过指针是可以修改被const修饰的那块内存的。</p> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdio.h&gt;</span></span>
<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token keyword">const</span> <span class="token keyword">int</span> a <span class="token operator">=</span> <span class="token number">2018</span><span class="token punctuation">;</span>
    <span class="token keyword">int</span> <span class="token operator">*</span>p <span class="token operator">=</span> <span class="token operator">&amp;</span>a<span class="token punctuation">;</span>
    <span class="token operator">*</span>p <span class="token operator">=</span> <span class="token number">2019</span><span class="token punctuation">;</span>
    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;%d\n&quot;</span><span class="token punctuation">,</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><p>DevC++虽然有一个警告：
<code>[Warning] initialization discards 'const' qualifier from pointer target type</code>
（[警告]初始化会从指针目标类型中丢弃'const'限定符）
但是还是可以修改！
可以看到，我们通过另外定义一个指针变量，将被const修饰的a的值改变了。	
此外，对于由于像数组溢出，隐式修改等程序不规范书写造成的运行过程中的修改，编译器是无能为力的，也说明const修饰的变量仍然是具备变量属性的。</p> <p>我们要知道的是，const关键字告诉了编译器，它修饰的变量不能被改变，如果代码中发现有类似改变该变量的操作，那么编译器就会捕捉这个错误。</p> <p>那么它在<b>实际中的意义之一</b>是什么呢？
帮助程序员提前发现问题，避免不该修改的值被意外地修改，但是无法完全保证不被修改！
也就是说，C语言中<b>const关键字是给编译器用的</b>帮助程序员提早发现可能存在的问题。
（所以给了个warning？但是却不给error，也是够了。）</p> <p>从这次的分析中，我们可以获得的思考：
1）<b>不要忽略编译器的警告，除非你很清楚在做什么</b>。（比如，上面我们用那些方法修改了const修饰的。）
2）虽然可以通过某种不正规途径修改const修饰的变量，但是在<b>工程中</b>永远不要这么做。
3）const关键字让编译器帮助我们发现变量不该被修改却被意外修改的错误。</p> <p><font color="pink">常见的问题：</font>
C语言中:</p> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token keyword">const</span> <span class="token keyword">int</span> maxn<span class="token operator">=</span><span class="token number">5</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> test<span class="token punctuation">[</span>maxn<span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token comment">//[Error] variably modified 'aa' at file scope</span>

<span class="token keyword">const</span> <span class="token keyword">int</span> maxn<span class="token operator">=</span><span class="token number">1000</span><span class="token operator">+</span><span class="token number">5</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> test<span class="token punctuation">[</span>maxn<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token comment">//编译出错，[Error] variably modified 'test' at file scope</span>
<span class="token comment">//在文件范围内可变地修改了“test”，因为数组的下标只接受常量，而C语言中const修饰的变量是个“假的常量”</span>
<span class="token comment">//当然，上面语法在Ｃ＋＋中是可以的，因为C++对C语言中const关键字进行了加强，使得真的是常量了，</span>
<span class="token comment">//而且，在C++中，还给const修饰而形成的常量，取名叫做const常量。</span>

</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div><h2 id="参考资料"><a href="#参考资料" class="header-anchor">#</a> 参考资料</h2> <ul><li>《C与指针》</li> <li>《C专家编程》</li> <li>《C缺陷与陷阱》</li> <li>《C Primer Plus（第6版)》，<a href="https://book.douban.com/search/%E6%99%AE%E6%8B%89%E8%BE%BE" target="_blank" rel="noopener noreferrer">普拉达 (Stephen Prata)<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>/译者: <a href="https://book.douban.com/search/%E5%A7%9C%E4%BD%91" target="_blank" rel="noopener noreferrer">姜佑<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li> <li>『CSDN C语言讲义』王保民</li> <li>『C语言指针详解』</li> <li>『C语言小白变怪兽 v1.0』，严长生，C语言中文网站长</li></ul></div> <div class="page-edit"><!----> <!----></div> <!----> </div> <!----></div></div>
    <script src="/assets/js/app.c70e21ad.js" defer></script><script src="/assets/js/15.fbdfc4ee.js" defer></script>
  </body>
</html>
